﻿#pragma once

#include <QObject>
#include <QIcon>
#include <QAction>
#include <Global.h>
#include "UIUtilsExport.h"

class QMenuBar;

namespace Domy {

/**
 * @brief The ActionManager class
 * @note  action管理器
 */
class UIUTILS_EXPORT ActionManager : public QObject
{
    Q_OBJECT
    explicit ActionManager(QWidget *parent = Q_NULLPTR);
public:
#define domy_act Domy::ActionManager::getInstance()
    static ActionManager *getInstance();

    ~ActionManager();

    /**
     * @brief registAction
     * @note  注册action
     * @param key     action键
     * @param text    显示文本
     * @param icon    图标
     * @param shorcut 快捷键
     */
    QAction *registAction(ActionKey key, const QString &text,
                          const QIcon &icon = QIcon(), const QKeySequence &shorcut = QKeySequence());

    /**
     * @brief getAction
     * @note  获取action
     * @param key action键
     */
    QAction *getAction(ActionKey key);

    /**
     * @brief setActionEnable
     * @note  设置action使能
     * @param key    action键
     * @param enable 使能状态
     */
    void setActionEnable(ActionKey key, bool enable);

    /**
     * @brief removeAction
     * @note  移除action
     * @param key action键
     */
    void removeAction(ActionKey key);

    /**
     * @brief triggerAction
     * @note  触发action
     * @param key action键
     */
    void triggerAction(ActionKey key);

    /**
     * @brief getMenuBar
     * @note  获取菜单栏
     */
    QMenuBar *getMenuBar();

    /**
     * @brief updateRecentFiles
     * @note  更新最近打开文件记录
     */
    void updateRecentFiles();

    /**
     * @brief addToolBarAction
     * @note  添加工具栏视窗action
     *        添加后若update为false则需要手动调用updateViewMenu更新视窗菜单
     * @param action
     * @param update 立即更新视窗菜单
     */
    void addToolBarAction(QAction *action, bool update = false);

    /**
     * @brief addDockWindowAction
     * @note  添加dock窗口action
     *        添加后若update为false则需要手动调用updateViewMenu更新视窗菜单
     * @param action
     * @param update 立即更新视窗菜单
     */
    void addDockWindowAction(QAction *action, bool update = false);

    /**
     * @brief updateViewMenu
     * @note  更新视窗菜单
     */
    void updateViewMenu();

signals:
    /**
     * @brief signalActionTriggered
     * @note  action触发信号
     * @param key        action键
     * @param is_checked 选中状态
     */
    void signalActionTriggered(ActionKey key, bool is_checked);

    /**
     * @brief signalRecentFileActionTriggered
     * @note  最近打开文件action触发信号
     * @param file_path 文件路径
     */
    void signalRecentFileActionTriggered(const QString &file_path);

private slots:
    void slotOnActionTriggered(bool is_checked);
    void slotOnRecentFileActionTriggered(bool is_checked);

private:
    void init();

    QAction *registRecentFileAction(const QString &text);

private:
    QMultiMap<ActionKey,
    QAction *>           m_action_map;

    QMenuBar            *m_menu_bar;

    QMenu               *m_menu_file;
    QMenu               *m_menu_edit;
    QMenu               *m_menu_view;
    QMenu               *m_menu_tools;
    QMenu               *m_menu_help;

    QList<QAction *>     m_tool_bar_actions;
    QList<QAction *>     m_dock_window_actions;
};

} // namespace Domy
